/*
 * @Author: EvanXU evanxu8023@163.com
 * @Date: 2024-03-03 09:40:58
 * @LastEditors: EvanXU evanxu8023@163.com
 * @LastEditTime: 2024-08-24 10:00:02
 * @FilePath: \program\USER\log\log.c
 * @Description: 
 *  xxx 
 * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. 
 */
#include <stdio.h>
#include <stdarg.h>
#include "log.h"

/**
 * @description: 默认的系统时间获取函数，如未注册其他事件获取函数则使用该函数
 * @return {*}  null
 */
static unsigned int default_get_sys_time_ms(void)
{
     return (unsigned int)0;
}
static get_sys_time_ms_def s_get_sys_time_ms = default_get_sys_time_ms;

/**
 * @description: 注册日志时间获取函数
 * @param {get_sys_time_ms_def} p_get_sys_time_ms  系统时间获取函数指针
 * @return {*}  null
 */
void log_time_register(get_sys_time_ms_def p_get_sys_time_ms)
{
    s_get_sys_time_ms = p_get_sys_time_ms;
}

/**
 * @description:    log打印函数
 * @param {enum log_color} color    日志等级对应的颜色
 * @param {char} *file              文件名
 * @param {int} line                行号
 * @param {char} *func              函数名
 * @param {char*} fmt               动态参数
 * @return {*} null
 */
void log_print(enum log_color color, const char *file, int line, const char *func, const char* fmt, ...)
{
    va_list ap;
    char buf[LOG_BUF_SIZE] = {0};
    long long time = s_get_sys_time_ms();

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

	switch(color)
	{
		case NULL_COLOR:
			printf("<%lld ms>[%s:%d %s] %s%s", time, file, line, func, buf, LOG_TAIL_CHAR);
		break;
		case ERROR_COLOR:
			printf("\033[%s<%lld ms>[E][%s:%d %s] %s%s\033[0m", LOG_COLOR_ERROR, time, file, line, func, buf, LOG_TAIL_CHAR);
		break;
		case DEBUG_COLOR:
			printf("\033[%s<%lld ms>[D]%s%s\033[0m", LOG_COLOR_DEBUG, time, buf, LOG_TAIL_CHAR);
		break;
		case WARN_COLOR:
			printf("\033[%s<%lld ms>[W][%s] %s%s\033[0m", LOG_COLOR_WARN, time, func, buf, LOG_TAIL_CHAR);
		break;
		case INFO_COLOR:
			//printf("\033[36;40;22m<%lld ms>[%s:%d %s] %s\033[0m", time, file, line, func, buf);
			printf("\033[%s<%lld ms>[I] %s%s\033[0m", LOG_COLOR_INFO, time, buf, LOG_TAIL_CHAR);
		break;
		default:
			break;
	}
}

/* 检查该字符是否属于ASCII码 */
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')

/**
 * @description:  将内存以hex编码方式打印
 * @param {char} *title_str     每行的头字符
 * @param {unsigned char} *buf  内存指针
 * @param {unsigned int} size   内存总字节数大小
 * @param {unsigned int} number 每行显示的字节数
 * @return {*}
 */
void log_dump_hex(const char *title_str, const unsigned char *buf, unsigned int size, unsigned int number)
{
    int i, j;

    /* 按行打印字符，每次步进一整行的字符数 */
    for (i = 0; i < size; i += number)
    {
        /* 打印每行表头字符 */
        printf("[%s]%08X: ", title_str, i);
        /* 打印每行行内十六进制字符 */
        for (j = 0; j < number; j++)
        {
            /* 每8个字符添加一个空格字符 */
            if (j % 8 == 0)
                printf(" ");
            /* 判断当前是否是最后一个字符 */
            if (i + j < size)
                printf("%02X ", buf[i + j]);
            else
                printf("   ");
        }
        /* 在16进制与ASCII码之间插入空格 */
        printf(" ");
        /* 打印每行16进制字符对应的ASCII码 */
        for (j = 0; j < number; j++)
        {
            if (i + j < size)
            {
                /* 检查该16进制数据是否属于ASCII码，是则打印ASCII码字符值，不是则打印小数点 */
                printf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
            }
        }
        /* 每行的行尾部，执行换行 */
        printf("\n");
    }
}



